package com.zyg.async;

import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

/**
 * 缺陷：
 * 获取任务结果的顺序无法确定，对于依赖性较强的业务情景无法满足
 * 会阻塞到当前所依赖的线程执行完毕
 * 内部基于自旋的方式，自旋时间过长，cpu空转，效率较低
 */
public class FutureTaskDemo {
    public static void main(String[] args) {
        FutureTask<Integer> futureTask1 = new FutureTask<>(new CalculateScore(2));
        FutureTask<Integer> futureTask2 = new FutureTask<>(new CalculateScore(5));
        FutureTask<Integer> futureTask3 = new FutureTask<>(new CalculateScore(4));
        Thread thread1 = new Thread(futureTask1);
        Thread thread2 = new Thread(futureTask2);
        Thread thread3 = new Thread(futureTask3);
        thread1.start();
        thread2.start();
        thread3.start();
        doSomeThing();
        Integer result1 = null;
        Integer result2 = null;
        Integer result3 = null;
        try {
            result1 = futureTask1.get();
        } catch (InterruptedException e) {
            futureTask1.cancel(true);
            e.printStackTrace();
        } catch (ExecutionException e) {
            futureTask1.cancel(true);
            e.printStackTrace();
        }
        try {
            result2 = futureTask2.get();
        } catch (InterruptedException e) {
            futureTask2.cancel(true);
            e.printStackTrace();
        } catch (ExecutionException e) {
            futureTask2.cancel(true);
            e.printStackTrace();
        }
        try {
            result3 = futureTask3.get();
        } catch (InterruptedException e) {
            futureTask3.cancel(true);
            e.printStackTrace();
        } catch (ExecutionException e) {
            futureTask3.cancel(true);
            e.printStackTrace();
        }
        System.out.println(result1+result2+result3);
    }

    private static void doSomeThing() {

        System.out.println("main thread execute");
    }

    private static class CalculateScore implements Callable<Integer> {
        private int num;

        public CalculateScore() {
        }

        public CalculateScore(int num) {
            this.num = num;
        }

        @Override
        public Integer call() throws Exception {
            Random random = new Random();
            TimeUnit.SECONDS.sleep(num);
            System.out.println(Thread.currentThread().getName());
            return random.nextInt(100);
        }
    }
}
